using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using unvell.ReoGrid;
using unvell.ReoGrid.CellTypes;
using unvell.ReoGrid.DataFormat;
using unvell.ReoGrid.Print;
using ZedGraph;

namespace ICP_MS.Plugin.Experiment;

internal class ReportClass : IDisposable
{
	private ExperimentDatas experiment = null;

	private ReoGridControl grid = null;

	private Worksheet sheetConc = null;

	private int sheetConcTotalPage = 0;

	private Worksheet sheetUcps = null;

	private int sheetUcpsTotalPage = 0;

	private Worksheet sheetCurve = null;

	private int sheetCurveTotalPage = 0;

	private Worksheet sheetStd = null;

	private int sheetStdTotalPage = 0;

	private Worksheet sheetCond = null;

	private int sheetCondTotalPage = 0;

	private Worksheet sheetCps = null;

	private int sheetCpsTotalPage = 0;

	private Worksheet sheetRatio = null;

	private int sheetRatioTotalPage = 0;

	private List<SamplesInfos> samples = new List<SamplesInfos>();

	private List<IsotopeInfos> isotopes = new List<IsotopeInfos>();

	private List<IsotopeCurve> curves = new List<IsotopeCurve>();

	private List<IsotopeRatio> ratios = new List<IsotopeRatio>();

	private int isotopeIdx = 0;

	private int ratioIdx = 0;

	private int sampleIdx = 0;

	private PrintDocument document = null;

	private int PageRows = 55;

	private int PageCols = 9;

	private int pageCount = 0;

	private ushort RowHeight = 19;

	private ushort ColumnWidth = 76;

	private int totalPages = 0;

	private ReportConfig config = new ReportConfig();

	private bool bShowRatio = false;

	private ManualResetEvent waitDispose = new ManualResetEvent(initialState: false);

	private float fzHeader = 9.5f;

	private float fzTitle = 10.5f;

	private float fzFooter = 9.5f;

	private float fzBody = 8f;

	public bool IsShowRatio
	{
		get
		{
			return bShowRatio;
		}
		set
		{
			bShowRatio = value;
		}
	}

	public ReportConfig Config
	{
		get
		{
			return config;
		}
		set
		{
			config = value;
		}
	}

	public PrintDocument Document => document;

	public int TotalPages => totalPages;

	public bool IsDisposed { get; set; }

	public event EventHandler BeginCreate;

	public event EventHandler EndCreate;

	public ReportClass(ExperimentDatas datas)
	{
		experiment = datas;
	}

	public void CreateDocument(PrinterSettings printerSettings = null, int pageindex = 1)
	{
		if (this.BeginCreate != null)
		{
			this.BeginCreate(null, EventArgs.Empty);
		}
		Task.Factory.StartNew(delegate
		{
			try
			{
				totalPages = 0;
				SetupWorksheet();
				SetupCondition();
				SetupCurves();
				SetupContents();
				SetupRatios();
				SetupDocument();
			}
			catch (Exception ex)
			{
				document = null;
				MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK);
			}
			finally
			{
				if (this.EndCreate != null)
				{
					this.EndCreate(null, EventArgs.Empty);
				}
				waitDispose.WaitOne();
				Dispose();
			}
		});
	}

	public void SetupDocument1()
	{
		List<PrintDocument> documents = new List<PrintDocument>();
		if (config.Cond)
		{
			documents.Add(sheetCond.CreatePrintSession().PrintDocument);
		}
		if (config.Curve)
		{
			documents.Add(sheetCurve.CreatePrintSession().PrintDocument);
		}
		if (config.Conc)
		{
			documents.Add(sheetConc.CreatePrintSession().PrintDocument);
		}
		if (config.Ucps)
		{
			documents.Add(sheetUcps.CreatePrintSession().PrintDocument);
		}
		if (config.Cps)
		{
			documents.Add(sheetCps.CreatePrintSession().PrintDocument);
		}
		if (documents.Count > 0)
		{
			document = new MultiPrintDocument(documents.ToArray());
			document.DocumentName = totalPages.ToString();
			document.EndPrint += delegate
			{
				waitDispose.Set();
			};
		}
		else
		{
			document = null;
		}
	}

	public void SetupDocument(PrinterSettings printerSettings = null, int pageindex = 0)
	{
		List<PrintDocument> documents = new List<PrintDocument>();
		List<int> totalPageList = new List<int>();
		using PrintSession session = grid.CreatePrintSession();
		while (session.Worksheets.Count > 0)
		{
			session.Worksheets.Remove(session.Worksheets.First());
		}
		if (config.Cond)
		{
			session.Worksheets.Add(grid.Worksheets["Condition"]);
			totalPageList.Add(sheetCondTotalPage);
		}
		if (config.Curve)
		{
			session.Worksheets.Add(grid.Worksheets["Curve"]);
			totalPageList.Add(sheetCurveTotalPage);
		}
		if (config.Conc)
		{
			session.Worksheets.Add(grid.Worksheets["Conc"]);
			totalPageList.Add(sheetConcTotalPage);
		}
		if (config.Ucps)
		{
			session.Worksheets.Add(grid.Worksheets["UCPS"]);
			totalPageList.Add(sheetUcpsTotalPage);
		}
		if (config.Cps)
		{
			session.Worksheets.Add(grid.Worksheets["CPS"]);
			totalPageList.Add(sheetCpsTotalPage);
		}
		if (bShowRatio)
		{
			session.Worksheets.Add(grid.Worksheets["Ratio"]);
			totalPageList.Add(sheetRatioTotalPage);
		}
		if (printerSettings != null && (printerSettings.PrintRange == PrintRange.SomePages || printerSettings.PrintRange == PrintRange.CurrentPage))
		{
			int pagestart = 0;
			int pageend = 0;
			if (printerSettings.PrintRange == PrintRange.SomePages)
			{
				pagestart = printerSettings.FromPage;
				pageend = printerSettings.ToPage;
			}
			else
			{
				pagestart = pageindex;
				pageend = pageindex;
			}
			List<PrintSelectedPage> printpages = GetPrintSomePage(pagestart, pageend, totalPageList.ToArray());
			if (printpages != null && printpages.Count > 0)
			{
				List<Worksheet> worksheets = new List<Worksheet>();
				foreach (PrintSelectedPage printpage in printpages)
				{
					if (printpage.StartPage <= printpage.EndPage)
					{
						Worksheet sheet = session.Worksheets.ElementAt(printpage.DocIndex);
						int startRow = (printpage.StartPage - 1) * PageRows;
						sheet.ClearAllPageBreaks();
						sheet.PrintableRange = new RangePosition(startRow, 0, PageRows * (printpage.EndPage - printpage.StartPage + 1), PageCols);
						sheet.AutoSplitPage();
						for (int i = printpage.StartPage; i < printpage.EndPage + 1; i++)
						{
							sheet.InsertRowPageBreak(i * PageRows);
						}
						worksheets.Add(sheet);
					}
				}
				while (session.Worksheets.Count > 0)
				{
					session.Worksheets.Remove(session.Worksheets.First());
				}
				foreach (Worksheet worksheet in worksheets)
				{
					documents.Add(worksheet.CreatePrintSession().PrintDocument);
				}
			}
		}
		else
		{
			foreach (Worksheet worksheet2 in session.Worksheets)
			{
				documents.Add(worksheet2.CreatePrintSession().PrintDocument);
			}
		}
		if (documents.Count > 0)
		{
			document = new MultiPrintDocument(documents.ToArray());
			document.DocumentName = totalPages.ToString();
			document.EndPrint += delegate
			{
				waitDispose.Set();
			};
		}
		else
		{
			document = null;
		}
	}

	public List<PrintSelectedPage> GetPrintSomePage(int startPage, int endPage, int[] TotalPage)
	{
		List<PrintSelectedPage> printSelectedPages = new List<PrintSelectedPage>();
		int sum = 0;
		int oldsum = 0;
		for (int i = 0; i < TotalPage.Count(); i++)
		{
			oldsum = sum;
			sum += TotalPage[i];
			if (sum >= startPage)
			{
				PrintSelectedPage ss = new PrintSelectedPage();
				ss.DocIndex = i;
				ss.StartPage = startPage - oldsum;
				if (endPage < sum)
				{
					ss.EndPage = endPage - oldsum;
					printSelectedPages.Add(ss);
					return printSelectedPages;
				}
				ss.EndPage = TotalPage[i];
				printSelectedPages.Add(ss);
				startPage = sum + 1;
			}
		}
		return printSelectedPages;
	}

	private void SetPageSettings(Worksheet sheet)
	{
		sheet.PrintSettings.Margins = new PageMargins(0.25f, 0.15f, 0.5f, 0.41f);
		sheet.PrintSettings.PaperName = "A4";
	}

	public void SetupWorksheet()
	{
		grid = new ReoGridControl();
		Worksheet sheet = grid.CurrentWorksheet;
		sheet.SetCols(PageCols);
		sheet.GetRangeStyles(RangePosition.EntireRange).HAlign = ReoGridHorAlign.Center;
		sheet.GetRangeStyles(RangePosition.EntireRange).VAlign = ReoGridVerAlign.Middle;
		int sheetIndex = 1;
		if (config.Conc)
		{
			sheetConc = grid.CopyWorksheet(sheet, sheetIndex++, "Conc");
			SetPageSettings(sheetConc);
		}
		if (config.Ucps)
		{
			sheetUcps = grid.CopyWorksheet(sheet, sheetIndex++, "UCPS");
			SetPageSettings(sheetUcps);
		}
		if (config.Cps)
		{
			sheetCps = grid.CopyWorksheet(sheet, sheetIndex++, "CPS");
			SetPageSettings(sheetCps);
		}
		if (bShowRatio)
		{
			sheetRatio = grid.CopyWorksheet(sheet, sheetIndex++, "Ratio");
			SetPageSettings(sheetRatio);
		}
		if (config.Cond)
		{
			sheetCond = grid.CopyWorksheet(sheet, sheetIndex++, "Condition");
			SetPageSettings(sheetCond);
		}
		if (config.Curve)
		{
			sheetCurve = grid.CopyWorksheet(sheet, sheetIndex++, "Curve");
			SetPageSettings(sheetCurve);
		}
		if (config.Std)
		{
			sheetStd = grid.CopyWorksheet(sheet, sheetIndex++, "Std");
			SetPageSettings(sheetStd);
		}
		grid.RemoveWorksheet(sheet);
	}

	private void SetupPageHeader(Worksheet sheet, int row)
	{
		sheet.SetRows(row + PageRows);
		if (config.Logo != null)
		{
			sheet.MergeRange(row, 0, 3, 2);
			Image image = config.Logo.Clone() as Image;
			sheet[row, 0] = new ImageCell(image);
		}
		if (config.Header != "")
		{
			sheet.MergeRange(row, 2, 1, PageCols - 2);
			WorksheetRangeStyle rangeStyle2 = new WorksheetRangeStyle();
			rangeStyle2.HAlign = ReoGridHorAlign.Center;
			rangeStyle2.VAlign = ReoGridVerAlign.Middle;
			rangeStyle2.FontSize = 8f;
			sheet.SetRangeStyles(new RangePosition(row, 2, 1, PageCols - 2), rangeStyle2);
			sheet.Ranges[row, 2, 1, PageCols - 2].Style.FontSize = 8f;
			sheet[row, 2] = config.Header;
		}
		if (config.Title != "")
		{
			sheet.MergeRange(row + 1, 2, 3, PageCols - 2);
			WorksheetRangeStyle rangeStyle = new WorksheetRangeStyle();
			rangeStyle.HAlign = ReoGridHorAlign.Left;
			rangeStyle.VAlign = ReoGridVerAlign.Middle;
			rangeStyle.FontSize = 12f;
			sheet.SetRangeStyles(new RangePosition(row + 1, 2, 3, PageCols - 2), rangeStyle);
			sheet.Ranges[row + 1, 2, 3, PageCols - 2].Style.FontSize = 12f;
			sheet[row + 1, 2] = config.Title;
		}
	}

	public void SetupCondition()
	{
		if (config.Cond)
		{
			pageCount = 0;
			SetupPageCondition(0);
			pageCount++;
			sheetCondTotalPage = pageCount;
			sheetCond.SetColumnsWidth(0, PageCols, ColumnWidth);
			sheetCond.SetRowsHeight(0, PageRows, RowHeight);
			sheetCond.ClearAllPageBreaks();
			sheetCond.InsertRowPageBreak(PageRows);
			totalPages += pageCount;
		}
	}

	private void SetupStd()
	{
	}

	public void SetupCurves()
	{
		if (!config.Curve)
		{
			return;
		}
		pageCount = 0;
		curves = new List<IsotopeCurve>();
		foreach (IsotopeInfos isotope in experiment.Isotopes)
		{
			if (!isotope.visible || isotope.inter)
			{
				continue;
			}
			foreach (IsotopeCurve curve in experiment.Curves)
			{
				if (curve.symbol == isotope.symbol && curve.calculated)
				{
					curves.Add(curve);
					break;
				}
			}
		}
		pageCount = 0;
		int curveNums;
		for (int curveIdx = 0; curveIdx < curves.Count; curveIdx += curveNums)
		{
			int rowNums = 0;
			curveNums = 0;
			rowNums += 7;
			for (int j = curveIdx; j < curves.Count; j++)
			{
				rowNums += 16 + curves[j].points;
				if (rowNums <= PageRows)
				{
					curveNums++;
					continue;
				}
				break;
			}
			SetupPageCurve(pageCount * PageRows, curveIdx, curveNums);
			pageCount++;
		}
		sheetCurveTotalPage = pageCount;
		totalPages += pageCount;
		sheetCurve.SetRowsHeight(0, sheetCurve.RowCount, RowHeight);
		sheetCurve.SetColumnsWidth(0, sheetCurve.ColumnCount, ColumnWidth);
		sheetCurve.ClearAllPageBreaks();
		for (int i = 0; i < pageCount * PageRows; i++)
		{
			if (i % PageRows == 0)
			{
				sheetCurve.InsertRowPageBreak(i);
			}
		}
	}

	private Image CreateCurve(double[] x1, double[] y1, double[] x2, double[] y2, string symbol)
	{
		Image image = null;
		try
		{
			using ZedGraphControl graph = new ZedGraphControl();
			GraphPane pane = graph.GraphPane;
			IEnumerable<IsotopeInfos> isotopeinfoUnit = experiment.Isotopes.Where((IsotopeInfos iso) => !iso.inter && iso.symbol == symbol);
			if (isotopeinfoUnit != null)
			{
				pane.XAxis.Title.Text = "浓度(" + isotopeinfoUnit.First().units + ")";
			}
			else
			{
				pane.XAxis.Title.Text = "浓度";
			}
			pane.YAxis.Title.Text = "强度";
			pane.Title.Text = symbol;
			LineItem line = pane.AddCurve("", x1, y1, Color.Blue, SymbolType.Circle);
			line.Line.IsVisible = false;
			pane.AddCurve("", x2, y2, Color.Black, SymbolType.None);
			pane.AxisChange();
			image = pane.GetImage(1101, 489, 96f);
		}
		catch (Exception ex)
		{
			image = null;
			Log.InsertLog("数据报表", "创建曲线出错", ex.Message, (Severity)3);
		}
		return image;
	}

	private void SetupPageCondition(int currentRow)
	{
		SetupPageHeader(sheetCond, currentRow);
		currentRow += 5;
		sheetCond.Ranges[currentRow, 0, 1, PageCols].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		sheetCond[currentRow, 0] = Lang.Txt("FormConfig.Columns.Extraction.Text");
		sheetCond[currentRow, 3] = Lang.Txt("FormConfig.Columns.D2.Text");
		sheetCond[currentRow, 2] = Lang.Txt("FormConfig.Columns.Hexapole.Text");
		sheetCond[currentRow, 1] = Lang.Txt("FormConfig.Columns.D1.Text");
		sheetCond[currentRow, 4] = Lang.Txt("FormConfig.Columns.DA.Text");
		sheetCond[currentRow, 5] = Lang.Txt("FormConfig.Columns.QE.Text");
		sheetCond[currentRow, 6] = Lang.Txt("FormConfig.Columns.F.Text");
		sheetCond[currentRow, 7] = Lang.Txt("FormConfig.Columns.L1.Text");
		sheetCond[currentRow, 8] = Lang.Txt("FormConfig.Columns.L2.Text");
		currentRow++;
		sheetCond.Ranges[currentRow, 0, 1, PageCols].Style.HorizontalAlign = ReoGridHorAlign.Center;
		sheetCond[currentRow, 0] = experiment.CurrentLens.Ex.ToString("F2");
		sheetCond[currentRow, 3] = experiment.CurrentLens.D2.ToString("F2");
		sheetCond[currentRow, 2] = experiment.CurrentLens.Pole.ToString("F2");
		sheetCond[currentRow, 1] = experiment.CurrentLens.D1.ToString("F2");
		sheetCond[currentRow, 4] = experiment.CurrentLens.DA.ToString("F2");
		sheetCond[currentRow, 5] = experiment.CurrentLens.QE.ToString("F2");
		sheetCond[currentRow, 6] = experiment.CurrentLens.F.ToString("F2");
		sheetCond[currentRow, 7] = experiment.CurrentLens.L1.ToString("F2");
		sheetCond[currentRow, 8] = experiment.CurrentLens.L2.ToString("F2");
		currentRow++;
		sheetCond.Ranges[currentRow, 0, 1, PageCols].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		sheetCond[currentRow, 0] = Lang.Txt("FormConfig.Columns.L3.Text");
		sheetCond[currentRow, 1] = Lang.Txt("FormConfig.Columns.Power.Text");
		sheetCond[currentRow, 2] = Lang.Txt("FormConfig.Columns.QuadPole.Text");
		sheetCond[currentRow, 3] = Lang.Txt("FormConfig.Columns.Collsion.Text");
		sheetCond[currentRow, 4] = Lang.Txt("FormConfig.Columns.Nebulizer.Text");
		sheetCond[currentRow, 5] = Lang.Txt("FormConfig.Columns.Carrier.Text");
		sheetCond[currentRow, 6] = Lang.Txt("FormConfig.Columns.CoolGas.Text");
		sheetCond[currentRow, 7] = Lang.Txt("FormConfig.Columns.X.Text");
		sheetCond[currentRow, 8] = Lang.Txt("FormConfig.Columns.Y.Text");
		currentRow++;
		sheetCond.Ranges[currentRow, 0, 1, PageCols].Style.HorizontalAlign = ReoGridHorAlign.Center;
		sheetCond[currentRow, 0] = experiment.CurrentLens.L3.ToString("F2");
		sheetCond[currentRow, 1] = experiment.CurrentPlasma.Power.ToString("F2");
		sheetCond[currentRow, 2] = experiment.CurrentRFS.quadPole.ToString("F2");
		sheetCond[currentRow, 3] = experiment.CurrentPlasma.Collision.ToString("F2");
		sheetCond[currentRow, 4] = experiment.CurrentPlasma.Auxiliary.ToString("F2");
		sheetCond[currentRow, 5] = experiment.CurrentPlasma.Nebuliser.ToString("F2");
		sheetCond[currentRow, 6] = experiment.CurrentPlasma.Cool.ToString("F2");
		sheetCond[currentRow, 7] = experiment.CurrentPlat.X.ToString("F2");
		sheetCond[currentRow, 8] = experiment.CurrentPlat.Y.ToString("F2");
		currentRow++;
		sheetCond.Ranges[currentRow, 0, 1, PageCols].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		sheetCond[currentRow, 0] = Lang.Txt("FormConfig.Columns.Z.Text");
		sheetCond[currentRow, 1] = Lang.Txt("FormConfig.Columns.Etp.Text");
		sheetCond[currentRow, 2] = Lang.Txt("FormConfig.Columns.Collsion2.Text");
		currentRow++;
		sheetCond[currentRow, 0] = experiment.CurrentPlat.Z.ToString("F2");
		sheetCond[currentRow, 1] = experiment.CurrentLens.Etp.ToString("F2");
		sheetCond[currentRow, 2] = experiment.CurrentPlasma.Collision2.ToString("F2");
		sheetCond.Ranges[currentRow, 0, 1, PageCols].Style.HorizontalAlign = ReoGridHorAlign.Center;
		sheetCond.MergeRange(PageRows - 1, 0, 1, PageCols);
		WorksheetRangeStyle worksheetRangeStyle = new WorksheetRangeStyle();
		worksheetRangeStyle.FontSize = 8f;
		worksheetRangeStyle.HAlign = ReoGridHorAlign.Center;
		worksheetRangeStyle.VAlign = ReoGridVerAlign.Middle;
		sheetCond[PageRows - 1, 0] = "分析条件--" + (pageCount + 1);
		sheetCond.SetRangeStyles(RangePosition.FromCellPosition(PageRows - 1, 0, PageRows - 1, PageCols), worksheetRangeStyle);
		sheetCond.Ranges[4, 0, PageRows - 3, PageCols].Style.FontSize = 8f;
	}

	private void SetupPageCurve(int currentRow, int curveIdx, int curveNums)
	{
		int startRow = currentRow;
		SetupPageHeader(sheetCurve, currentRow);
		currentRow += 5;
		for (int i = 0; i < curveNums; i++)
		{
			IsotopeCurve curve = curves[curveIdx + i];
			List<StatisticResults> results = (from result in experiment.Statistics
				from sample in experiment.Samples
				where result.symbol == curve.symbol && result.stdCon >= 0.0 && result.sampleId == sample.guid && (sample.type == 0 || sample.type == curve.method) && sample.status == 1
				select result).ToList();
			results.Sort((StatisticResults r0, StatisticResults r1) => r0.stdCon.CompareTo(r1.stdCon));
			currentRow++;
			IEnumerable<double> cps1 = from result in results
				where result.include
				select result.avgCPS;
			IEnumerable<double> con1 = from result in results
				where result.include
				select result.stdCon;
			double[] con2 = con1.ToArray();
			double[] cps2 = new double[con2.Length];
			for (int j = 0; j < con2.Length; j++)
			{
				cps2[j] = con2[j] * curve.k + curve.b;
			}
			Image image = CreateCurve(con1.ToArray(), cps1.ToArray(), con2.ToArray(), cps2.ToArray(), curve.symbol);
			if (image != null)
			{
				sheetCurve.MergeRange(currentRow, 1, 12, PageCols - 2);
				sheetCurve[new RangePosition(currentRow, 1, 12, PageCols - 2)] = new ImageCell(image);
			}
			currentRow += 12;
			string formular = $"y = {curve.k:0.00} * x + {curve.b:0.00}; R2 = {curve.r:0.00000}";
			IEnumerable<IsotopeInfos> isotopeinfoUnit = experiment.Isotopes.Where((IsotopeInfos iso) => !iso.inter && iso.symbol == curve.symbol);
			if (isotopeinfoUnit != null)
			{
				formular = formular + "  (" + isotopeinfoUnit.First().units + ")";
			}
			currentRow++;
			sheetCurve.MergeRange(currentRow, 1, 1, PageCols - 2);
			sheetCurve[currentRow, 1] = formular;
			currentRow++;
			sheetCurve.Ranges[currentRow, 2, 1, 5].Data = new string[5] { "样品名", "标准浓度", "计算浓度", "CPS", "参与计算" };
			sheetCurve.Ranges[currentRow, 2, 1, 5].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
			currentRow++;
			foreach (StatisticResults result2 in results)
			{
				sheetCurve.Ranges[currentRow++, 2, 1, 5].Data = new string[5]
				{
					result2.label,
					string.Format(new FormatValue(), "{0:U}", result2.stdCon),
					string.Format(new FormatValue(), "{0:U}", result2.avgCon),
					string.Format(new FormatValue(), "{0:U}", result2.avgCPS),
					result2.include.ToString()
				};
			}
		}
		sheetCurve.MergeRange(startRow + PageRows - 1, 0, 1, PageCols);
		WorksheetRangeStyle worksheetRangeStyle = new WorksheetRangeStyle();
		worksheetRangeStyle.FontSize = 8f;
		worksheetRangeStyle.HAlign = ReoGridHorAlign.Center;
		worksheetRangeStyle.VAlign = ReoGridVerAlign.Middle;
		sheetCurve.SetRangeStyles(RangePosition.FromCellPosition(startRow + PageRows - 3, 0, startRow + PageRows - 3, PageCols), worksheetRangeStyle);
		sheetCurve[startRow + PageRows - 1, 0] = "工作曲线--" + (pageCount + 1);
		sheetCurve.Ranges[startRow + 4, 0, PageRows - 4, PageCols].Style.FontSize = 8f;
		sheetCurve.Ranges[startRow + 4, 0, PageRows - 4, PageCols].Style.FontName = "SimSun";
	}

	public void SetupContents()
	{
		if (!config.Conc && !config.Cps && !config.Ucps)
		{
			return;
		}
		samples = experiment.Samples.Where((SamplesInfos sample) => sample.report && sample.status == 1).ToList();
		isotopes = experiment.Isotopes.Where((IsotopeInfos isotope) => isotope.visible).ToList();
		pageCount = 0;
		for (isotopeIdx = 0; isotopeIdx < isotopes.Count; isotopeIdx += PageCols - 1)
		{
			int isotopeNums = Math.Min(PageCols - 1, isotopes.Count - isotopeIdx);
			sampleIdx = 0;
			while (sampleIdx < samples.Count)
			{
				int rowNums = 0;
				int sampleNums = 0;
				rowNums += 8;
				for (int j = sampleIdx; j < samples.Count; j++)
				{
					rowNums++;
					if (experiment.ReportParams.ShowRuns)
					{
						rowNums += samples[j].mains;
					}
					rowNums++;
					if (experiment.ReportParams.ShowSd)
					{
						rowNums++;
					}
					if (experiment.ReportParams.ShowRsd)
					{
						rowNums++;
					}
					if (rowNums <= PageRows)
					{
						sampleNums++;
						continue;
					}
					break;
				}
				SetupContPage(pageCount * PageRows, sampleNums, isotopeNums);
				pageCount++;
				sampleIdx += sampleNums;
			}
		}
		if (config.Conc)
		{
			totalPages += pageCount;
			sheetConcTotalPage = pageCount;
		}
		if (config.Cps)
		{
			totalPages += pageCount;
			sheetCpsTotalPage = pageCount;
		}
		if (config.Ucps)
		{
			totalPages += pageCount;
			sheetUcpsTotalPage = pageCount;
		}
		if (config.Cps)
		{
			sheetCps.SetRowsHeight(0, sheetCps.RowCount, RowHeight);
			sheetCps.SetColumnsWidth(0, sheetCps.ColumnCount, ColumnWidth);
			sheetCps.ClearAllPageBreaks();
			for (int l = 0; l < pageCount * PageRows; l++)
			{
				if (l % PageRows == 0)
				{
					sheetCps.InsertRowPageBreak(l);
				}
			}
		}
		if (config.Ucps)
		{
			sheetUcps.SetRowsHeight(0, sheetUcps.RowCount, RowHeight);
			sheetUcps.SetColumnsWidth(0, sheetUcps.ColumnCount, ColumnWidth);
			sheetUcps.ClearAllPageBreaks();
			for (int k = 0; k < pageCount * PageRows; k++)
			{
				if (k % PageRows == 0)
				{
					sheetUcps.InsertRowPageBreak(k);
				}
			}
		}
		if (!config.Conc)
		{
			return;
		}
		sheetConc.SetRowsHeight(0, sheetConc.RowCount, RowHeight);
		sheetConc.SetColumnsWidth(0, sheetConc.ColumnCount, ColumnWidth);
		sheetConc.ClearAllPageBreaks();
		for (int i = 0; i < pageCount * PageRows; i++)
		{
			if (i % PageRows == 0)
			{
				sheetConc.InsertRowPageBreak(i);
			}
		}
	}

	public void SetupRatios()
	{
		if (!bShowRatio)
		{
			return;
		}
		samples = experiment.Samples.Where((SamplesInfos sample) => sample.report && sample.status == 1).ToList();
		ratios = experiment.Ratios.Select((IsotopeRatio ratio) => ratio).ToList();
		pageCount = 0;
		for (ratioIdx = 0; ratioIdx < ratios.Count; ratioIdx += PageCols - 1)
		{
			int ratioNums = Math.Min(PageCols - 1, ratios.Count - ratioIdx);
			sampleIdx = 0;
			while (sampleIdx < samples.Count)
			{
				int rowNums = 0;
				int sampleNums = 0;
				rowNums += 8;
				for (int i = sampleIdx; i < samples.Count; i++)
				{
					rowNums++;
					if (experiment.ReportParams.ShowRuns)
					{
						rowNums += samples[i].mains;
					}
					rowNums++;
					if (experiment.ReportParams.ShowSd)
					{
						rowNums++;
					}
					if (experiment.ReportParams.ShowRsd)
					{
						rowNums++;
					}
					if (rowNums <= PageRows - 2)
					{
						sampleNums++;
						continue;
					}
					break;
				}
				SetupContRatioPage(pageCount * PageRows, sampleNums, ratioNums);
				pageCount++;
				sampleIdx += sampleNums;
			}
		}
		if (bShowRatio && ratios.Count > 0)
		{
			totalPages += pageCount;
			sheetRatioTotalPage = pageCount;
		}
	}

	private void SetupContPage(Worksheet sheet, int type, int currentRow, int sampleNums, int isotopeNums)
	{
		int startRow = currentRow;
		SetupPageHeader(sheet, currentRow);
		currentRow += 5;
		sheet.MergeRange(currentRow, 0, 1, 1);
		sheet[currentRow, 0] = "样品\\元素";
		sheet.Ranges[currentRow, 1, 1, PageCols - 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		sheet.Ranges[currentRow, 1, 1, PageCols - 1].Style.Bold = true;
		for (int k = 0; k < isotopeNums; k++)
		{
			IsotopeInfos isotope3 = isotopes[k + isotopeIdx];
			sheet[currentRow, k + 1] = isotope3.symbol;
		}
		currentRow++;
		for (int l = 0; l < sampleNums; l++)
		{
			SamplesInfos sample = samples[sampleIdx + l];
			sheet.MergeRange(currentRow, 1, 1, PageCols - 1);
			sheet.Cells[currentRow, 1].Style.HAlign = ReoGridHorAlign.Left;
			sheet[currentRow, 1] = sample.label;
			currentRow++;
			for (int m = 0; m < sample.mains; m++)
			{
				sheet[m + currentRow, 0] = (m + 1).ToString();
				for (int j = 0; j < isotopeNums; j++)
				{
					IsotopeInfos isotope2 = experiment.Isotopes[j + isotopeIdx];
					AnalyseInfos value2 = experiment.Results.Where((AnalyseInfos result) => result.sampleId == sample.guid && result.symbol == isotope2.symbol && result.number == m).First();
					double r = 0.0;
					switch (type)
					{
					case 0:
						r = value2.concentration;
						break;
					case 1:
						r = value2.intensity;
						break;
					case 2:
						r = value2.icps;
						break;
					}
					sheet[currentRow + m, j + 1] = string.Format(new FormatValue(), "{0:U}", r);
					if (isotope2.inter)
					{
						sheet.Cells[currentRow + m, j + 1].Style.BackColor = Color.Yellow;
						if (type == 2)
						{
							sheet.Cells[currentRow + m, j + 1].DataFormat = CellDataFormatFlag.Percent;
						}
					}
					if (value2.exclude)
					{
						sheet.Cells[currentRow + m, j + 1].Style.TextColor = Color.Red;
					}
				}
			}
			currentRow += sample.mains;
			sheet[currentRow, 0] = "χ";
			sheet[currentRow + 1, 0] = "σ";
			sheet[currentRow + 2, 0] = "RSD%";
			sheet.Ranges[currentRow, 1, 1, PageCols - 1].Style.Bold = true;
			sheet.Ranges[currentRow, 1, 1, PageCols - 1].Style.TextColor = Color.Blue;
			sheet.Ranges[currentRow + 1, 1, 1, PageCols - 1].Style.TextColor = Color.Blue;
			sheet.Ranges[currentRow + 2, 1, 1, PageCols - 1].Style.TextColor = Color.Blue;
			for (int i = 0; i < isotopeNums; i++)
			{
				IsotopeInfos isotope = isotopes[i + isotopeIdx];
				StatisticResults value = experiment.Statistics.Where((StatisticResults result) => result.sampleId == sample.guid && result.symbol == isotope.symbol).First();
				double r2 = 0.0;
				double r3 = 0.0;
				double r4 = 0.0;
				switch (type)
				{
				case 0:
					r2 = value.avgCon;
					r3 = value.sdCon;
					r4 = value.rsdCon;
					break;
				case 1:
					r2 = value.avgUICPS;
					r3 = value.sdUICPS;
					r4 = value.rsdUICPS;
					break;
				case 2:
					r2 = value.avgCPS;
					r3 = value.sdCPS;
					r4 = value.rsdCPS;
					break;
				}
				sheet[currentRow, i + 1] = string.Format(new FormatValue(), "{0:U}", r2);
				sheet[currentRow + 1, i + 1] = string.Format(new FormatValue(), "{0:U}", r3);
				sheet[currentRow + 2, i + 1] = string.Format(new FormatValue(), "{0:U}", r4);
				if (isotope.inter)
				{
					sheet.Ranges[currentRow, i + 1, 3, 1].Style.BackColor = Color.Yellow;
				}
			}
			currentRow += 3;
		}
		sheet.Ranges[startRow + 5, 0, currentRow - startRow - 5, 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		string footer = "";
		switch (type)
		{
		case 0:
			footer = $"计算浓度--{pageCount + 1}";
			break;
		case 1:
			footer = $"原始强度--{pageCount + 1}";
			break;
		case 2:
			footer = $"校正强度--{pageCount + 1}";
			break;
		}
		sheet.MergeRange(startRow + PageRows - 2, 0, 1, PageCols);
		sheet[startRow + PageRows - 2, 0] = footer;
	}

	private void SetupContRatioPage(Worksheet sheet, int type, int currentRow, int sampleNums, int isotopeNums)
	{
		int startRow = currentRow;
		SetupPageHeader(sheet, currentRow);
		currentRow += 5;
		sheet.MergeRange(currentRow, 0, 1, 1);
		sheet[currentRow, 0] = "样品\\元素";
		sheet.Ranges[currentRow, 1, 1, PageCols - 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		sheet.Ranges[currentRow, 1, 1, PageCols - 1].Style.Bold = true;
		for (int k = 0; k < isotopeNums; k++)
		{
			IsotopeInfos isotope3 = isotopes[k + isotopeIdx];
			sheet[currentRow, k + 1] = isotope3.symbol;
		}
		currentRow++;
		for (int l = 0; l < sampleNums; l++)
		{
			SamplesInfos sample = samples[sampleIdx + l];
			sheet.MergeRange(currentRow, 1, 1, PageCols - 1);
			sheet.Cells[currentRow, 1].Style.HAlign = ReoGridHorAlign.Left;
			sheet[currentRow, 1] = sample.label;
			currentRow++;
			for (int m = 0; m < sample.mains; m++)
			{
				sheet[m + currentRow, 0] = (m + 1).ToString();
				for (int j = 0; j < isotopeNums; j++)
				{
					IsotopeInfos isotope2 = experiment.Isotopes[j + isotopeIdx];
					AnalyseInfos value2 = experiment.Results.Where((AnalyseInfos result) => result.sampleId == sample.guid && result.symbol == isotope2.symbol && result.number == m).First();
					double r = 0.0;
					switch (type)
					{
					case 0:
						r = value2.concentration;
						break;
					case 1:
						r = value2.intensity;
						break;
					case 2:
						r = value2.icps;
						break;
					}
					sheet[currentRow + m, j + 1] = string.Format(new FormatValue(), "{0:U}", r);
					if (isotope2.inter)
					{
						sheet.Cells[currentRow + m, j + 1].Style.BackColor = Color.Yellow;
						if (type == 2)
						{
							sheet.Cells[currentRow + m, j + 1].DataFormat = CellDataFormatFlag.Percent;
						}
					}
					if (value2.exclude)
					{
						sheet.Cells[currentRow + m, j + 1].Style.TextColor = Color.Red;
					}
				}
			}
			currentRow += sample.mains;
			sheet[currentRow, 0] = "χ";
			sheet[currentRow + 1, 0] = "σ";
			sheet[currentRow + 2, 0] = "RSD%";
			sheet.Ranges[currentRow, 1, 1, PageCols - 1].Style.Bold = true;
			sheet.Ranges[currentRow, 1, 1, PageCols - 1].Style.TextColor = Color.Blue;
			sheet.Ranges[currentRow + 1, 1, 1, PageCols - 1].Style.TextColor = Color.Blue;
			sheet.Ranges[currentRow + 2, 1, 1, PageCols - 1].Style.TextColor = Color.Blue;
			for (int i = 0; i < isotopeNums; i++)
			{
				IsotopeInfos isotope = isotopes[i + isotopeIdx];
				StatisticResults value = experiment.Statistics.Where((StatisticResults result) => result.sampleId == sample.guid && result.symbol == isotope.symbol).First();
				double r2 = 0.0;
				double r3 = 0.0;
				double r4 = 0.0;
				switch (type)
				{
				case 0:
					r2 = value.avgCon;
					r3 = value.sdCon;
					r4 = value.rsdCon;
					break;
				case 1:
					r2 = value.avgUICPS;
					r3 = value.sdUICPS;
					r4 = value.rsdUICPS;
					break;
				case 2:
					r2 = value.avgCPS;
					r3 = value.sdCPS;
					r4 = value.rsdCPS;
					break;
				}
				sheet[currentRow, i + 1] = string.Format(new FormatValue(), "{0:U}", r2);
				sheet[currentRow + 1, i + 1] = string.Format(new FormatValue(), "{0:U}", r3);
				sheet[currentRow + 2, i + 1] = string.Format(new FormatValue(), "{0:U}", r4);
				if (isotope.inter)
				{
					sheet.Ranges[currentRow, i + 1, 3, 1].Style.BackColor = Color.Yellow;
				}
			}
			currentRow += 3;
		}
		sheet.Ranges[startRow + 5, 0, currentRow - startRow - 5, 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		string footer = "";
		switch (type)
		{
		case 0:
			footer = $"计算浓度--{pageCount + 1}";
			break;
		case 1:
			footer = $"原始强度--{pageCount + 1}";
			break;
		case 2:
			footer = $"校正强度--{pageCount + 1}";
			break;
		}
		sheet.MergeRange(startRow + PageRows - 2, 0, 1, PageCols);
		sheet[startRow + PageRows - 2, 0] = footer;
	}

	private void SetupContPage(int currentRow, int sampleNums, int isotopeNums)
	{
		int startRow = currentRow;
		ContSetPageHeader(currentRow);
		currentRow += 5;
		ContSetHeader(currentRow);
		for (int k = 0; k < isotopeNums; k++)
		{
			IsotopeInfos isotope3 = isotopes[k + isotopeIdx];
			ContSetIsotope(currentRow, k + 1, isotope3.symbol);
		}
		currentRow++;
		for (int l = 0; l < sampleNums; l++)
		{
			SamplesInfos sample = samples[sampleIdx + l];
			if (config.CustomData)
			{
				ContSetSampleName(currentRow, isotopeNums, sample.label + "    " + config.Datatime.ToString("yyyy/MM/dd") + sample.time.ToString(" HH:mm:ss"));
			}
			else
			{
				ContSetSampleName(currentRow, isotopeNums, sample.label + "    " + sample.time.ToString("yyyy/MM/dd HH:mm:ss"));
			}
			currentRow++;
			if (experiment.ReportParams.ShowRuns)
			{
				for (int m = 0; m < sample.mains; m++)
				{
					ContSetNumber(currentRow, m);
					for (int j = 0; j < isotopeNums; j++)
					{
						IsotopeInfos isotope2 = isotopes[j + isotopeIdx];
						AnalyseInfos value2 = experiment.Results.Where((AnalyseInfos result) => result.sampleId == sample.guid && result.symbol == isotope2.symbol && result.number == m).First();
						ContSetResult(m + currentRow, j + 1, value2, isotope2.inter);
					}
				}
				currentRow += sample.mains;
			}
			ContSetStatHeader(currentRow, isotopeNums);
			for (int i = 0; i < isotopeNums; i++)
			{
				IsotopeInfos isotope = isotopes[i + isotopeIdx];
				IEnumerable<StatisticResults> value = experiment.Statistics.Where((StatisticResults result) => result.sampleId == sample.guid && result.symbol == isotope.symbol);
				if (value.Count() > 0)
				{
					ContSetStatResult(currentRow, i + 1, value.First(), isotope.inter);
				}
			}
			if (experiment.ReportParams.ShowMean)
			{
				currentRow++;
			}
			if (experiment.ReportParams.ShowSd)
			{
				currentRow++;
			}
			if (experiment.ReportParams.ShowRsd)
			{
				currentRow++;
			}
		}
		ContSetFistColumnBackground(startRow + 5, currentRow - startRow - 5);
		ContSetFooter(startRow + PageRows - 1);
		currentRow += 2;
	}

	private void SetupContRatioPage(int currentRow, int sampleNums, int ratioNums)
	{
		int startRow = currentRow;
		ContRatioSetPageHeader(currentRow);
		currentRow += 5;
		ContRatioSetHeader(currentRow);
		for (int k = 0; k < ratios.Count(); k++)
		{
			IsotopeRatio ratio3 = ratios[k];
			ContSetRatio(currentRow, k + 1, ratio3.Name);
		}
		currentRow++;
		for (int l = 0; l < sampleNums; l++)
		{
			SamplesInfos sample = samples[sampleIdx + l];
			if (config.CustomData)
			{
				ContRatioSetSampleName(currentRow, ratioNums, sample.label + "    " + config.Datatime.ToString("yyyy/MM/dd") + sample.time.ToString(" HH:mm:ss"));
			}
			else
			{
				ContRatioSetSampleName(currentRow, ratioNums, sample.label + "    " + sample.time.ToString("yyyy/MM/dd HH:mm:ss"));
			}
			currentRow++;
			if (experiment.ReportParams.ShowRuns)
			{
				for (int m = 0; m < sample.mains; m++)
				{
					ContSetRatioNumber(currentRow, m);
					for (int j = 0; j < ratioNums; j++)
					{
						IsotopeRatio ratio2 = ratios[j + ratioIdx];
						RatioResults ratioresult = experiment.RatioResults.Where((RatioResults result) => result.SampleId == sample.guid && result.Name == ratio2.Name && result.Number == m).First();
						ContSetRatioResult(m + currentRow, j + 1, ratioresult);
					}
				}
				currentRow += sample.mains;
			}
			ContSetRatioStatHeader(currentRow, ratioNums);
			for (int i = 0; i < ratioNums; i++)
			{
				IsotopeRatio ratio = ratios[i + ratioIdx];
				IEnumerable<RatioStatistics> value = experiment.RatioStat.Where((RatioStatistics result) => result.SampleId == sample.guid && result.Name == ratio.Name);
				if (value.Count() > 0)
				{
					ContRatioSetStatResult(currentRow, i + 1, value.First());
				}
			}
			if (experiment.ReportParams.ShowMean)
			{
				currentRow++;
			}
			if (experiment.ReportParams.ShowSd)
			{
				currentRow++;
			}
			if (experiment.ReportParams.ShowRsd)
			{
				currentRow++;
			}
		}
		ContRatioSetFistColumnBackground(startRow + 5, currentRow - startRow - 5);
		ContRatioSetFooter(startRow + PageRows - 3);
		currentRow += 2;
	}

	private void ContSetPageHeader(int row)
	{
		if (config.Conc)
		{
			SetupPageHeader(sheetConc, row);
		}
		if (config.Cps)
		{
			SetupPageHeader(sheetCps, row);
		}
		if (config.Ucps)
		{
			SetupPageHeader(sheetUcps, row);
		}
	}

	private void ContRatioSetPageHeader(int row)
	{
		if (bShowRatio)
		{
			SetupPageHeader(sheetRatio, row);
		}
	}

	private void ContSetHeader(int row)
	{
		if (config.Conc)
		{
			sheetConc.MergeRange(row, 0, 1, 1);
			sheetConc[row, 0] = "样品\\元素";
			sheetConc.Ranges[row, 1, 1, PageCols - 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
			sheetConc.Ranges[row, 1, 1, PageCols - 1].Style.Bold = true;
		}
		if (config.Cps)
		{
			sheetCps.MergeRange(row, 0, 1, 1);
			sheetCps[row, 0] = "样品\\元素";
			sheetCps.Ranges[row, 1, 1, PageCols - 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
			sheetCps.Ranges[row, 1, 1, PageCols - 1].Style.Bold = true;
		}
		if (config.Ucps)
		{
			sheetUcps.MergeRange(row, 0, 1, 1);
			sheetUcps[row, 0] = "样品\\元素";
			sheetUcps.Ranges[row, 1, 1, PageCols - 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
			sheetUcps.Ranges[row, 1, 1, PageCols - 1].Style.Bold = true;
		}
	}

	private void ContRatioSetHeader(int row)
	{
		if (bShowRatio)
		{
			sheetRatio.MergeRange(row, 0, 1, 1);
			sheetRatio[row, 0] = "样品\\元素";
			sheetRatio.Ranges[row, 1, 1, PageCols - 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
			sheetRatio.Ranges[row, 1, 1, PageCols - 1].Style.Bold = true;
		}
	}

	private void ContSetIsotope(int row, int col, string symbol)
	{
		if (config.Conc)
		{
			IEnumerable<IsotopeInfos> isotopeinfoUnit = experiment.Isotopes.Where((IsotopeInfos iso) => !iso.inter && iso.symbol == symbol);
			if (isotopeinfoUnit != null && isotopeinfoUnit.Count() > 0)
			{
				sheetConc[row, col] = symbol + "(" + isotopeinfoUnit.First().units + ")";
			}
			else
			{
				sheetConc[row, col] = symbol;
			}
		}
		if (config.Ucps)
		{
			sheetUcps[row, col] = symbol;
		}
		if (config.Cps)
		{
			sheetCps[row, col] = symbol;
		}
	}

	private void ContSetRatio(int row, int col, string ratio)
	{
		if (config.Cps)
		{
			sheetRatio[row, col] = ratio;
		}
	}

	private void ContSetSampleName(int row, int cols, string label)
	{
		if (config.Conc)
		{
			sheetConc.MergeRange(row, 1, 1, PageCols - 1);
			sheetConc.Cells[row, 1].Style.HAlign = ReoGridHorAlign.Left;
			sheetConc[row, 1] = label;
			sheetConc.SetRangeBorders(new RangePosition(row, 1, 1, cols), BorderPositions.Bottom, new RangeBorderStyle(Color.Black, BorderLineStyle.BoldSolid));
		}
		if (config.Cps)
		{
			sheetCps.MergeRange(row, 1, 1, PageCols - 1);
			sheetCps.Cells[row, 1].Style.HAlign = ReoGridHorAlign.Left;
			sheetCps[row, 1] = label;
			sheetCps.SetRangeBorders(new RangePosition(row, 1, 1, cols), BorderPositions.Bottom, new RangeBorderStyle(Color.Black, BorderLineStyle.BoldSolid));
		}
		if (config.Ucps)
		{
			sheetUcps.MergeRange(row, 1, 1, PageCols - 1);
			sheetUcps.Cells[row, 1].Style.HAlign = ReoGridHorAlign.Left;
			sheetUcps[row, 1] = label;
			sheetUcps.SetRangeBorders(new RangePosition(row, 1, 1, cols), BorderPositions.Bottom, new RangeBorderStyle(Color.Black, BorderLineStyle.BoldSolid));
		}
	}

	private void ContRatioSetSampleName(int row, int cols, string label)
	{
		if (bShowRatio)
		{
			sheetRatio.MergeRange(row, 1, 1, PageCols - 1);
			sheetRatio.Cells[row, 1].Style.HAlign = ReoGridHorAlign.Left;
			sheetRatio[row, 1] = label;
			sheetRatio.SetRangeBorders(new RangePosition(row, 1, 1, cols), BorderPositions.Bottom, new RangeBorderStyle(Color.Black, BorderLineStyle.BoldSolid));
		}
	}

	private void ContSetNumber(int row, int m)
	{
		if (config.Conc)
		{
			sheetConc[m + row, 0] = (m + 1).ToString();
		}
		if (config.Cps)
		{
			sheetCps[m + row, 0] = (m + 1).ToString();
		}
		if (config.Ucps)
		{
			sheetUcps[m + row, 0] = (m + 1).ToString();
		}
	}

	private void ContSetRatioNumber(int row, int m)
	{
		if (bShowRatio)
		{
			sheetRatio[m + row, 0] = (m + 1).ToString();
		}
	}

	private void ContSetResult(int row, int col, AnalyseInfos result, bool inter)
	{
		if (config.Conc)
		{
			if (inter)
			{
				sheetConc.Cells[row, col].Style.BackColor = Color.Yellow;
				sheetConc[row, col] = string.Format(new FormatPercent(), "{0:U}", result.concentration);
			}
			else
			{
				sheetConc[row, col] = string.Format(new FormatValue(), "{0:U}", result.concentration);
			}
			if (result.exclude)
			{
				sheetConc.Cells[row, col].Style.TextColor = Color.Red;
			}
		}
		if (config.Cps)
		{
			if (inter)
			{
				sheetCps.Cells[row, col].Style.BackColor = Color.Yellow;
				sheetCps[row, col] = string.Format(new FormatPercent(), "{0:U}", result.concentration);
			}
			else
			{
				sheetCps[row, col] = string.Format(new FormatValue(), "{0:U}", result.icps);
			}
			if (result.exclude)
			{
				sheetCps.Cells[row, col].Style.TextColor = Color.Red;
			}
		}
		if (config.Ucps)
		{
			sheetUcps[row, col] = string.Format(new FormatValue(), "{0:U}", result.intensity);
			if (inter)
			{
				sheetUcps.Cells[row, col].Style.BackColor = Color.Yellow;
			}
			if (result.exclude)
			{
				sheetUcps.Cells[row, col].Style.TextColor = Color.Red;
			}
		}
	}

	private void ContSetRatioResult(int row, int col, RatioResults result)
	{
		if (bShowRatio)
		{
			sheetRatio[row, col] = string.Format(new FormatValue(), "{0:U}", result.Result);
		}
	}

	private void ContSetStatHeaderSingle(Worksheet sheet, int row, int cols)
	{
		if (experiment.ReportParams.ShowMean)
		{
			sheet.Ranges[row, 1, 1, PageCols - 1].Style.TextColor = Color.Black;
			sheet.SetRangeBorders(new RangePosition(row, 1, 1, cols), BorderPositions.Bottom, new RangeBorderStyle(Color.Black, BorderLineStyle.Solid));
			sheet[row++, 0] = "χ";
		}
		if (experiment.ReportParams.ShowSd)
		{
			sheet.Ranges[row, 1, 1, PageCols - 1].Style.TextColor = Color.Blue;
			sheet[row++, 0] = "σ";
		}
		if (experiment.ReportParams.ShowRsd)
		{
			sheet.Ranges[row, 1, 1, PageCols - 1].Style.TextColor = Color.Blue;
			sheet[row++, 0] = "RSD%";
		}
	}

	private void ContSetStatHeader(int row, int cols)
	{
		if (config.Conc)
		{
			ContSetStatHeaderSingle(sheetConc, row, cols);
		}
		if (config.Cps)
		{
			ContSetStatHeaderSingle(sheetCps, row, cols);
		}
		if (config.Ucps)
		{
			ContSetStatHeaderSingle(sheetUcps, row, cols);
		}
	}

	private void ContSetRatioStatHeader(int row, int cols)
	{
		if (bShowRatio)
		{
			ContSetStatHeaderSingle(sheetRatio, row, cols);
		}
	}

	private void ContSetStatResult(int row, int col, StatisticResults result, bool inter)
	{
		if (config.Conc)
		{
			int concRow = row;
			if (experiment.ReportParams.ShowMean)
			{
				sheetConc.Ranges[concRow, col, 1, 1].Style.Bold = true;
				if (inter)
				{
					sheetConc.Ranges[concRow, col, 1, 1].Style.BackColor = Color.Yellow;
					sheetConc[concRow++, col] = string.Format(new FormatPercent(), "{0:U}", result.avgCon);
				}
				else
				{
					sheetConc[concRow++, col] = string.Format(new FormatValue(), "{0:U}", result.avgCon);
				}
			}
			if (experiment.ReportParams.ShowSd)
			{
				if (inter)
				{
					sheetConc.Ranges[concRow, col, 1, 1].Style.BackColor = Color.Yellow;
				}
				sheetConc[concRow++, col] = string.Format(new FormatValue(), "{0:U}", result.sdCon);
			}
			if (experiment.ReportParams.ShowRsd)
			{
				if (inter)
				{
					sheetConc.Ranges[concRow, col, 1, 1].Style.BackColor = Color.Yellow;
				}
				sheetConc[concRow++, col] = string.Format(new FormatValue(), "{0:U}", result.rsdCon);
			}
		}
		if (config.Cps)
		{
			int cpsRow = row;
			if (experiment.ReportParams.ShowMean)
			{
				sheetCps.Ranges[cpsRow, col, 1, 1].Style.Bold = true;
				if (inter)
				{
					sheetCps.Ranges[cpsRow, col, 1, 1].Style.BackColor = Color.Yellow;
					sheetCps[cpsRow++, col] = string.Format(new FormatPercent(), "{0:U}", result.avgCPS);
				}
				else
				{
					sheetCps[cpsRow++, col] = string.Format(new FormatValue(), "{0:U}", result.avgCPS);
				}
			}
			if (experiment.ReportParams.ShowSd)
			{
				if (inter)
				{
					sheetCps.Ranges[cpsRow, col, 1, 1].Style.BackColor = Color.Yellow;
				}
				sheetCps[cpsRow++, col] = string.Format(new FormatValue(), "{0:U}", result.sdCPS);
			}
			if (experiment.ReportParams.ShowRsd)
			{
				if (inter)
				{
					sheetCps.Ranges[cpsRow, col, 1, 1].Style.BackColor = Color.Yellow;
				}
				sheetCps[cpsRow++, col] = string.Format(new FormatValue(), "{0:U}", result.rsdCPS);
			}
		}
		if (!config.Ucps)
		{
			return;
		}
		int ucpsRow = row;
		if (experiment.ReportParams.ShowMean)
		{
			sheetUcps.Ranges[ucpsRow, col, 1, 1].Style.Bold = true;
			if (inter)
			{
				sheetUcps.Ranges[ucpsRow, col, 1, 1].Style.BackColor = Color.Yellow;
			}
			sheetUcps[ucpsRow++, col] = string.Format(new FormatValue(), "{0:U}", result.avgUICPS);
		}
		if (experiment.ReportParams.ShowSd)
		{
			if (inter)
			{
				sheetUcps.Ranges[ucpsRow, col, 1, 1].Style.BackColor = Color.Yellow;
			}
			sheetUcps[ucpsRow++, col] = string.Format(new FormatValue(), "{0:U}", result.sdUICPS);
		}
		if (experiment.ReportParams.ShowRsd)
		{
			if (inter)
			{
				sheetUcps.Ranges[row, col, 1, 1].Style.BackColor = Color.Yellow;
			}
			sheetUcps[ucpsRow++, col] = string.Format(new FormatValue(), "{0:U}", result.rsdUICPS);
		}
	}

	private void ContRatioSetStatResult(int row, int col, RatioStatistics result)
	{
		if (bShowRatio)
		{
			int ucpsRow = row;
			if (experiment.ReportParams.ShowMean)
			{
				sheetRatio[ucpsRow++, col] = result.Avg.ToString("F3");
			}
			if (experiment.ReportParams.ShowSd)
			{
				sheetRatio[ucpsRow++, col] = result.Sd.ToString("F3");
			}
			if (experiment.ReportParams.ShowRsd)
			{
				sheetRatio[ucpsRow++, col] = result.Rsd.ToString("F3");
			}
		}
	}

	private void ContSetFistColumnBackground(int startRow, int endRow)
	{
		if (config.Conc)
		{
			sheetConc.Ranges[startRow, 0, endRow, 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		}
		if (config.Cps)
		{
			sheetCps.Ranges[startRow, 0, endRow, 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		}
		if (config.Ucps)
		{
			sheetUcps.Ranges[startRow, 0, endRow, 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		}
	}

	private void ContRatioSetFistColumnBackground(int startRow, int endRow)
	{
		if (bShowRatio)
		{
			sheetRatio.Ranges[startRow, 0, endRow, 1].Style.BackColor = Color.FromKnownColor(KnownColor.Control);
		}
	}

	private void ContSetFooter(int row)
	{
		if (config.Conc)
		{
			sheetConc.MergeRange(row, 0, 1, PageCols);
			WorksheetRangeStyle worksheetRangeStyle3 = new WorksheetRangeStyle();
			worksheetRangeStyle3.FontSize = 8f;
			worksheetRangeStyle3.HAlign = ReoGridHorAlign.Center;
			worksheetRangeStyle3.VAlign = ReoGridVerAlign.Middle;
			sheetConc.SetRangeStyles(new RangePosition(row, 0, 1, PageCols), worksheetRangeStyle3);
			sheetConc[row, 0] = $"计算浓度--{pageCount + 1}";
			sheetConc.Ranges[row - PageRows + 4, 0, PageRows - 3, PageCols].Style.FontSize = 8f;
			sheetConc.Ranges[row - PageRows + 4, 0, PageRows - 3, PageCols].Style.FontName = "SimSun";
		}
		if (config.Cps)
		{
			sheetCps.MergeRange(row, 0, 1, PageCols);
			WorksheetRangeStyle worksheetRangeStyle2 = new WorksheetRangeStyle();
			worksheetRangeStyle2.FontSize = 8f;
			worksheetRangeStyle2.HAlign = ReoGridHorAlign.Center;
			worksheetRangeStyle2.VAlign = ReoGridVerAlign.Middle;
			sheetCps.SetRangeStyles(new RangePosition(row, 0, 1, PageCols), worksheetRangeStyle2);
			sheetCps[row, 0] = $"校正强度--{pageCount + 1}";
			sheetCps.Ranges[row - PageRows + 4, 0, PageRows - 3, PageCols].Style.FontSize = 8f;
			sheetCps.Ranges[row - PageRows + 4, 0, PageRows - 3, PageCols].Style.FontName = "SimSun";
		}
		if (config.Ucps)
		{
			sheetUcps.MergeRange(row, 0, 1, PageCols);
			WorksheetRangeStyle worksheetRangeStyle = new WorksheetRangeStyle();
			worksheetRangeStyle.FontSize = 8f;
			worksheetRangeStyle.HAlign = ReoGridHorAlign.Center;
			worksheetRangeStyle.VAlign = ReoGridVerAlign.Middle;
			sheetUcps.SetRangeStyles(new RangePosition(row, 0, 1, PageCols), worksheetRangeStyle);
			sheetUcps[row, 0] = $"原始强度--{pageCount + 1}";
			sheetUcps.Cells[row, 0].Style.FontSize = 8f;
			sheetUcps.Ranges[row - PageRows + 4, 0, PageRows - 3, PageCols].Style.FontSize = 8f;
			sheetUcps.Ranges[row - PageRows + 4, 0, PageRows - 3, PageCols].Style.FontName = "SimSun";
		}
	}

	private void ContRatioSetFooter(int row)
	{
		if (bShowRatio)
		{
			sheetRatio.MergeRange(row, 0, 1, PageCols);
			WorksheetRangeStyle worksheetRangeStyle = new WorksheetRangeStyle();
			worksheetRangeStyle.FontSize = 8f;
			worksheetRangeStyle.HAlign = ReoGridHorAlign.Center;
			worksheetRangeStyle.VAlign = ReoGridVerAlign.Middle;
			sheetRatio.SetRangeStyles(RangePosition.FromCellPosition(row, 0, row, PageCols), worksheetRangeStyle);
			sheetRatio[row, 0] = $"元素比率--{pageCount + 1}";
		}
	}

	public void Dispose()
	{
		if (!IsDisposed)
		{
			IsDisposed = true;
			if (document != null)
			{
				document.Dispose();
			}
			if (grid != null)
			{
				grid.Reset();
				grid.Dispose();
			}
			curves = null;
			samples = null;
			isotopes = null;
		}
	}
}
